package org.kenewstar.file.controller;

import org.kenewstar.common.bean.dto.FileAndFolderDto;
import org.kenewstar.common.bean.pojo.MicroFile;
import org.kenewstar.common.bean.pojo.MicroUser;
import org.kenewstar.common.constant.CommonConstant;
import org.kenewstar.common.utils.AssertUtil;
import org.kenewstar.common.utils.CommonResult;
import org.kenewstar.file.config.PathProperties;
import org.kenewstar.file.dto.DiskFileData;
import org.kenewstar.file.dto.SearchFilesDto;
import org.kenewstar.file.dto.UpdateNameDto;
import org.kenewstar.file.mapper.FileMapper;
import org.kenewstar.file.service.FileService;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;

/**
 * 文件控制器
 * @author xinke.huang@hand-china.com
 * @version 1.0
 * @date 2021/2/28
 */
@RestController
@CrossOrigin(value = CommonConstant.API_HOST,allowCredentials = "true")
@RequestMapping("/file")
public class FileController {

    @Resource
    private FileService fileService;
    @Resource
    private PathProperties pathProperties;
    @Resource
    private FileMapper fileMapper;

    /**
     * 文件上传
     * @param fid 父id
     * @param file 文件对象
     * @param request request
     * @return result
     * @throws IOException exception
     */
    @PostMapping("/upload/files")
    public CommonResult uploadFile(@RequestParam(required = false,defaultValue = "-1")Long fid,
                                   MultipartFile file, HttpServletRequest request) throws IOException {

        // 获取用户对象
        HttpSession session = request.getSession();
        MicroUser user = (MicroUser) session.getAttribute(CommonConstant.SESSION_USER);
        if (validateStoreSpace(file, user)) {
            return CommonResult.failed("存储空间不足");
        }
        // 执行
        List<FileAndFolderDto> dtoList = fileService.uploadFile(fid, file, user);
        // 返回成功消息
        return CommonResult.success(dtoList);
    }

    /**
     * 校验存储空间
     * @param file multipart
     * @param user 用户id
     * @return boolean
     */
    private boolean validateStoreSpace(MultipartFile file, MicroUser user) {
        // 文件字节数
        long bytes = file.getSize();
        // 用户已用字节数
        Long byteSum = fileMapper.selectSumFileByte(user.getId());
        long sum = Objects.isNull(byteSum) ? 0 : byteSum;
        // 用户可用字节数
        long notUsedBytes = user.getDiskSize() * CommonConstant.GB - sum;

        return bytes > notUsedBytes;
    }

    /**
     * 修改文件或文件夹名称
     * @param dto 修改参名
     * @return result
     */
    @PostMapping("/update/name")
    public CommonResult updateName(@RequestBody UpdateNameDto dto){
        AssertUtil.notNull(dto);
        int result = fileService.updateName(dto);
        return CommonResult.success(result);
    }

    /**
     * 文件下载
     * @param response
     * @throws IOException exception
     */
    @GetMapping("/download/file")
    public ResponseEntity<byte[]> downloadFile(Long id, HttpServletResponse response) throws IOException {
        AssertUtil.notNull(id);
        // 根据id查询文件信息
        MicroFile microFile = fileService.getFileById(id);
        // 获取文件存储的位置
        String storePath = pathProperties.getStorePath() + microFile.getDiskFilename();
        // 下载文件名
        String filename = new String(microFile.getFilename().getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1);
        // 创建文件对象
        File file = new File(storePath);

        InputStream is = new FileInputStream(file);
        byte[] buffer = new byte[is.available()];
        is.read(buffer);
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Content-Length", String.valueOf(file.length()));
        httpHeaders.add("Content-Disposition",
                "attachment;filename=" + filename);
        HttpStatus status = HttpStatus.OK;
        return new ResponseEntity<>(buffer, httpHeaders, status);

    }

    /**
     * 搜索文件
     * @param dto 查询参数
     * @param session session
     * @return result
     */
    @PostMapping("/search/files")
    public CommonResult searchFiles(@RequestBody SearchFilesDto dto,HttpSession session) {
        AssertUtil.notNull(dto);
        // 获取用户信息
        MicroUser user = (MicroUser) session.getAttribute(CommonConstant.SESSION_USER);
        // 执行查询
        List<FileAndFolderDto> dtoList = fileService.searchFiles(user.getId(), dto.getFilename());
        // 返回文件数据
        return CommonResult.success(dtoList);
    }

    /**
     * 统计用户磁盘占用空间
     * @param session session
     * @return result
     */
    @GetMapping("/total/size")
    public CommonResult totalUsedFileSize(HttpSession session) {
        // 获取用户信息
        MicroUser user = (MicroUser) session.getAttribute(CommonConstant.SESSION_USER);
        List<DiskFileData> diskFileData = fileService.totalUsedFileSize(user);
        return CommonResult.success(diskFileData);
    }


}
